import {
  HTMLProps,
  Children,
  createElement,
  cloneElement,
  isValidElement,
  useState,
  useEffect,
  useCallback,
  CSSProperties,
} from 'react';
import cls from 'classnames';
import { Property } from 'csstype';
import styles from './index.module.scss';

export interface SlideItemProps extends HTMLProps<any> {
  width: Property.Width;
  height: Property.Height;
}

export const SlideItem = ({
  width,
  height,
  className,
  children,
  style,
  ...others
}: SlideItemProps) => {
  style = {
    width,
    height,
    ...style
  };
  return (
    <div
      className={cls(styles.item, className)}
      style={style}
      {...others}
    >{children}</div>
  )
}

export interface CarouselProps extends HTMLProps<any> {
  activeStyle?: CSSProperties;
  widthChangeFactor?: number;
}

const CENTER_Z_INDEX = 200;
const ACTIVE_CLASSNAME = 'asf-carousel-active';

export default ({
  className,
  children,
  style,
  activeStyle,
  widthChangeFactor,
  ...others
}: CarouselProps) => {
  const [activeIndex, setActiveIndex] = useState(0);
  const [newChildren, setNewChildren] = useState<any[]>([]);
  const [offset, setOffset] = useState<Property.Width>('0');
  const [slider, setSlider] = useState<any>(null);
  // const [activeItem, setActiveItem] = useState<any>(null);

  useEffect(() => {
    setNewChildren(Children.map(children, (child, idx) => {
      if (!isValidElement(child)) return child;

      return child.type === 'li'
        ? cloneElement(
          child,
          {
            className: cls(
              styles.item,
              activeIndex === idx && [styles.active, ACTIVE_CLASSNAME],
              child.props.className,
            ),
            onClick: () => {
              setActiveIndex(idx);
              child.props.onClick && child.props.onClick();
            },
            style: {
              ...child.props.style,
              ...activeIndex === idx && activeStyle,
              zIndex: CENTER_Z_INDEX - Math.abs(idx - activeIndex),
            },
            // ...activeIndex === idx && {
            //   ref: (item: any) => setActiveItem(item)
            // },
          },
        )
        : createElement(
          'li',
          {
            className: cls(
              styles.item,
              activeIndex === idx && styles.active,
            ),
            onClick: () => {
              setActiveIndex(idx);
              child.props.onClick && child.props.onClick();
            },
          },
          child,
        );
    }) || []);
    if (!slider) return;
    const items = (slider as any).children;
    const item = items[activeIndex];
    if (!item) return;
    const _offset = document.body.clientWidth / 2 - item.offsetLeft - item.clientWidth / 2 + 'px';
    setOffset(_offset);
  }, [activeIndex, children, slider]);

  return (
    <div
      className={cls(styles.slides, className)}
      {...others}
    >
      <ul
        className={styles.slidesInner}
        ref={useCallback(node => setSlider(node), [])}
        style={{ transform: `translateX(${offset})`, }}
      >
        {newChildren}
      </ul>
    </div>
  )
}
